package com.engine.shunsheng.service.impl;

import com.engine.core.impl.Service;
import com.engine.kq.biz.KQGroupMemberComInfo;
import com.engine.shunsheng.service.LeaveDevService;
import com.engine.shunsheng.util.SsUtil;
import org.apache.commons.lang3.StringUtils;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chenwnj
 * @date 2023/11/14
 * @description
 **/
public class LeaveDevServiceImpl extends Service implements LeaveDevService {

    BaseBean bb = new BaseBean();
    /**
     * 日期格式，年月日，用横杠分开，例如：2023-11-14
     */
    public static final String DATE_FORMAT_YY_MM_DD = "yyyy-MM-dd";
    @Override
    public Map<String, Object> getLeaveDuration(Map<String, Object> params) {

        Map<String, Object> result = new HashMap<>();
        Map< String, Object> shiftInfo = new HashMap<>();

        RecordSet rs = new RecordSet();

        String resourceId = Util.null2String(params.get("resourceId"));
        String newLeaveType = Util.null2String(params.get("newLeaveType"));
        String fromDate = Util.null2String(params.get("fromDate"));
        String fromTime = Util.null2String(params.get("fromTime"));
        String toDate = Util.null2String(params.get("toDate"));
        String toTime = Util.null2String(params.get("toTime"));

        bb.writeLog("newLeaveType: " + newLeaveType);
        bb.writeLog("fromDate: " + fromDate);
        bb.writeLog("fromTime: " + fromTime);
        bb.writeLog("toDate: " + toDate);
        bb.writeLog("toTime: " + toTime);

        if ( StringUtils.isBlank(resourceId)) {
            result.put("code",500);
            result.put("msg","请先选择请假人员");
            return result;
        }
        if ( StringUtils.isBlank(fromDate) || StringUtils.isBlank(fromTime) ||
                StringUtils.isBlank(toDate) || StringUtils.isBlank(toTime) ) {
            result.put("code",500);
            result.put("msg","请先选择请假开始时间和结束时间");
            return result;
        }
        if ( !fromDate.equals(toDate)) {
            result.put("code",500);
            result.put("msg","请假开始时间和结束时间不在同一天");
            return result;
        }

        //根据人员去获取当天的班次信息
        KQGroupMemberComInfo kqGroupMemberComInfo = new KQGroupMemberComInfo();
        String groupId = kqGroupMemberComInfo.getKQGroupId(resourceId, toDate);
        bb.writeLog("groupId: " + groupId);
        //判断请假结束日期是周几--该公司是固班制，不需要考虑排班制
        SsUtil ssUtil = new SsUtil();
        String numberOfWeek = ssUtil.getNumberOfWeek(toDate);
        bb.writeLog("numberOfWeek: " + numberOfWeek);

        String serialid = "";
        String acqSerialSql = "SELECT serialid from kq_fixedschedulce where groupid = ? and weekday = ? ";
        rs.executeQuery(acqSerialSql, groupId, numberOfWeek);
        while ( rs.next()) {
            serialid = Util.null2String(rs.getString("serialid"));
        }
        bb.writeLog("serialid: " + serialid);
        //根据班次获取当前班次是否为弹性制班次，是，获取最早开始时间和最晚开始时间
        if (StringUtils.isNotBlank(serialid)) {
            String acqStartEndTimeSql = "select times,onoffworktype from kq_ShiftOnOffWorkSections where (isdelete is null or isdelete = 0) and serialid = ? ";
            rs.executeQuery( acqStartEndTimeSql,serialid);
            while ( rs.next()) {
                String times = Util.null2String(rs.getString("times"));
                String onoffworktype = Util.null2String(rs.getString("onoffworktype"));
                if ( StringUtils.isNotBlank(onoffworktype) && "start".equals(onoffworktype)) {
                    shiftInfo.put("startTime",times);
                }
                if ( StringUtils.isNotBlank(onoffworktype) && "end".equals(onoffworktype)) {
                    shiftInfo.put("endTime",times);
                }
            }
            bb.writeLog("shiftInfo: " + shiftInfo);

            String acqTanxingSql = "select b.advancetime,b.postponetime,b.ruledetailtype " +
                    "from kq_ShiftPersonalizedRule a " +
                    "left join kq_ShiftPersonalizedRuleDetail b " +
                    "on b.personalizedruleid = a.id " +
                    "where a.serialid = ? and b.enable = 1 and (a.isdelete = 0 or a.isdelete is null)";
            rs.executeQuery( acqTanxingSql,serialid);
            bb.writeLog("acqTanxingSql: " + acqTanxingSql);
            while ( rs.next()) {
                String advancetime = Util.null2String(rs.getString("advancetime"));
                String postponetime = Util.null2String(rs.getString("postponetime"));
                String ruledetailtype = Util.null2String(rs.getString("ruledetailtype"));
                if ( StringUtils.isNotBlank(ruledetailtype) && "earlyinearlyout".equalsIgnoreCase(ruledetailtype)) {
                    String startTime = Util.null2String( shiftInfo.get("startTime"));
                    String endTime = Util.null2String( shiftInfo.get("endTime"));
                    Integer advancetimeInt = -Integer.parseInt(advancetime);
                    String minStartTime = ssUtil.getCalTime(startTime, advancetimeInt);
                    Integer postponetimeInt = -Integer.parseInt(postponetime);
                    String minEndTime = ssUtil.getCalTime(endTime, postponetimeInt);
                    shiftInfo.put("minStartTime",minStartTime);
                    shiftInfo.put("minEndTime",minEndTime);
                }
                if ( StringUtils.isNotBlank(ruledetailtype) && "lateinLateOut".equalsIgnoreCase(ruledetailtype)) {
                    String startTime = Util.null2String( shiftInfo.get("startTime"));
                    String endTime = Util.null2String( shiftInfo.get("endTime"));
                    Integer advancetimeInt = Integer.parseInt(advancetime);
                    String maxStartTime = ssUtil.getCalTime(startTime, advancetimeInt);
                    Integer postponetimeInt = Integer.parseInt(postponetime);
                    String maxEndTime = ssUtil.getCalTime(endTime, postponetimeInt);
                    shiftInfo.put("maxStartTime",maxStartTime);
                    shiftInfo.put("maxEndTime",maxEndTime);
                }
            }
            //获取休息时间
            String acqRestSql = "select resttype, time from kq_ShiftRestTimeSections where (isdelete = 0 or isdelete is null) and serialid = ?";
            rs.executeQuery(acqRestSql, serialid);
            while (rs.next()) {
                String resttype = Util.null2String(rs.getString("resttype"));
                String time = Util.null2String(rs.getString("time"));
                if (StringUtils.isNotBlank(resttype) && "start".equals(resttype)) {
                    shiftInfo.put("reststart",time);
                }
                if (StringUtils.isNotBlank(resttype) && "end".equals(resttype)) {
                    shiftInfo.put("restend",time);
                }
            }
            //获取班次最大工作时长
            String acqWorkTimeSql = "select worktime from kq_ShiftManagement where id = ?  ";
            rs.executeQuery(acqWorkTimeSql, serialid);
            while ( rs.next()) {
                String worktime = Util.null2String(rs.getString("worktime"));
                if ( StringUtils.isNotBlank(worktime)) {
                    shiftInfo.put("worktime",worktime);
                }
            }

        }
        bb.writeLog("shiftInfo: " + shiftInfo);

        //班次最早开始时间，最晚开始时间
        String minStartTime = StringUtils.isBlank( Util.null2String( shiftInfo.get("minStartTime"))) ?
                Util.null2String( shiftInfo.get("startTime")) : Util.null2String( shiftInfo.get("minStartTime"));
        bb.writeLog("minStartTime: " + minStartTime);
        String maxStartTime = StringUtils.isBlank( Util.null2String( shiftInfo.get("maxStartTime"))) ?
                Util.null2String( shiftInfo.get("startTime")) : Util.null2String( shiftInfo.get("maxStartTime"));
        bb.writeLog("maxStartTime: " + maxStartTime);
        String restStartTime = Util.null2String( shiftInfo.get("reststart"));
        String restEndTime = Util.null2String( shiftInfo.get("restend"));

        String duration = "0";
        if ( minStartTime.compareTo(fromTime) <= 0 && maxStartTime.compareTo(fromTime) >= 0) {//请假开始时间在该班次允许时间范围内
            //考虑休息时间
            String beginTime = fromTime;
            String endTime = toTime;
            //是否计算时间
            boolean isOne = true;
            //是否计算两段时间
            boolean isTwo = false;
            if ( StringUtils.isNotBlank(restStartTime) && StringUtils.isNotBlank(restStartTime)) {
                //fromtime<reststart
                if (fromTime.compareTo(restStartTime) < 0 && toTime.compareTo(restStartTime) <= 0 ){

                }
                if (fromTime.compareTo(restStartTime) < 0 && toTime.compareTo(restStartTime) > 0 && toTime.compareTo(restEndTime) <= 0) {
                    endTime = restStartTime;
                }
                if (fromTime.compareTo(restStartTime) < 0 && toTime.compareTo(restStartTime) > 0 && toTime.compareTo(restEndTime) > 0) {
                    isTwo = true;
                }
                if (fromTime.compareTo(restStartTime) >= 0 && toTime.compareTo(restEndTime) <= 0) {
                    isOne = false;
                }
                if (fromTime.compareTo(restStartTime) >= 0 && fromTime.compareTo(restEndTime) < 0 && toTime.compareTo(restEndTime) > 0) {
                    beginTime = restEndTime;
                }
            }

            long time = ssUtil.getTime(beginTime, endTime);
            bb.writeLog("time: " + time);
            if ( !isOne) {
                time = 0;
            }
            if (isTwo) {
                long restTime = ssUtil.getTime(restStartTime, restEndTime);
                time = time - restTime;
            }
            //不可超过班次的工作时长
            Integer worktime = Util.getIntValue(Util.null2String(shiftInfo.get("worktime")));
            if ( worktime >0) {
                if (time > worktime) {
                    time = worktime;
                }
            }

            BigDecimal longTime = new BigDecimal(time);

            //根据假期类型获取请假单位
            //最小请假单位：1-按天请假 2-按半天请假 3-按小时请假 4-按整天请假 5-半小时 6-整小时
            Integer minimumUnit = 3;
            String acqMinimumUnitSql = "select minimumUnit from kq_leaveRules where id = ? ";
            rs.executeQuery( acqMinimumUnitSql, newLeaveType);
            while ( rs.next()) {
                minimumUnit = Util.getIntValue(Util.null2String(rs.getString("minimumUnit")));
            }
            bb.writeLog("minimumUnit: " + minimumUnit);
            if ( minimumUnit <= 0) {
                result.put("code",500);
                result.put("msg","假期类型没有设置最小请假单位");
                return result;
            }
            if ( minimumUnit == 1) {
                BigDecimal b = new BigDecimal("60");//小时
                BigDecimal unit = new BigDecimal("8");
                BigDecimal divisor = b.multiply(unit);
                bb.writeLog("divisor: " + divisor);
                duration = String.valueOf(longTime.divide(divisor,2, RoundingMode.HALF_UP));
            }
            if ( minimumUnit == 2) {
                BigDecimal b = new BigDecimal("60");//小时
                BigDecimal unit = new BigDecimal("4");
                BigDecimal divisor = b.multiply(unit);
                bb.writeLog("divisor: " + divisor);
                duration = String.valueOf(longTime.divide(divisor,2, RoundingMode.HALF_UP));
            }
            if ( minimumUnit == 3 || minimumUnit == 5 || minimumUnit == 6 ) {
                BigDecimal b = new BigDecimal("60");//小时
                duration = String.valueOf(longTime.divide(b,2, RoundingMode.HALF_UP));
            }
            if ( minimumUnit == 4) {
                BigDecimal b = new BigDecimal("60");//小时
                BigDecimal unit = new BigDecimal("24");
                BigDecimal divisor = b.multiply(unit);
                bb.writeLog("divisor: " + divisor);
                duration = String.valueOf(longTime.divide(divisor,2, RoundingMode.HALF_UP));
            }

            bb.writeLog("duration: " + duration);
        } else if (minStartTime.compareTo(fromTime) > 0 && "00:00".compareTo(fromTime) <= 0){
            result.put("code",500);
            result.put("msg","开始时间早于班次最早开始时间，请重新选择");
            return result;
        } else if (maxStartTime.compareTo(fromTime) < 0) {
            result.put("code",500);
            result.put("msg","开始时间迟于班次最晚开始时间，请重新选择");
            return result;
        }
        result.put("code",200);
        result.put("msg","请求成功");
        result.put("data",duration);

        return result;
    }
}
